/*-------------------------------------------------------------------------
 *
 * ipc.h
 *	  POSTGRES 进程间通信定义.
 *
 * 此文件命名不当，因为它现在与 IPC 直接关系不大.
 * 这里的功能涉及管理后端或后台的退出时间清理.
 *
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/storage/ipc.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef IPC_H
#define IPC_H

typedef void (*pg_on_exit_callback) (int code, Datum arg);
typedef void (*shmem_startup_hook_type) (void);

/*----------
 * 处理在代码块中发生的ereport(ERROR)或ereport(FATAL)退出期间必须进行的清理的API。
 * （典型示例是撤消对共享内存状态的瞬态更改。）
 *
 *		PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg);
 *		{
 *			... 可能抛出 ereport(ERROR) 或 ereport(FATAL) 的代码 ...
 *		}
 *		PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg);
 *
 * 其中清理代码在每个pg_on_exit_callback声明的函数中。
 * Datum值 "arg" 可以携带清理函数所需的任何信息。
 *
 * 该构造确保在 ERROR 或 FATAL 退出期间将调用cleanup_function()。
 * 在控制代码成功退出时不会调用它。 （如果您希望在此时也发生它，
 * 请在构造后立即自行调用该函数。）
 *
 * 注意：宏参数被多次求值，因此请避免副作用。
 *----------
 */
#define PG_ENSURE_ERROR_CLEANUP(cleanup_function, arg)	\
	do { \
		before_shmem_exit(cleanup_function, arg); \
		PG_TRY()

#define PG_END_ENSURE_ERROR_CLEANUP(cleanup_function, arg)	\
		cancel_before_shmem_exit(cleanup_function, arg); \
		PG_CATCH(); \
		{ \
			cancel_before_shmem_exit(cleanup_function, arg); \
			cleanup_function (0, arg); \
			PG_RE_THROW(); \
		} \
		PG_END_TRY(); \
	} while (0)


/* ipc.c */
extern PGDLLIMPORT bool proc_exit_inprogress;
extern PGDLLIMPORT bool shmem_exit_inprogress;

extern void proc_exit(int code) pg_attribute_noreturn();
extern void shmem_exit(int code);
extern void on_proc_exit(pg_on_exit_callback function, Datum arg);
extern void on_shmem_exit(pg_on_exit_callback function, Datum arg);
extern void before_shmem_exit(pg_on_exit_callback function, Datum arg);
extern void cancel_before_shmem_exit(pg_on_exit_callback function, Datum arg);
extern void on_exit_reset(void);
extern void check_on_shmem_exit_lists_are_empty(void);

/* ipci.c */
extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook;

extern Size CalculateShmemSize(int *num_semaphores);
extern void CreateSharedMemoryAndSemaphores(void);
extern void InitializeShmemGUCs(void);

#endif							/* IPC_H */
